﻿using System;
using System.Collections.Specialized;
using System.Web.Security;
using Eneta.Portal.Common;
using Microsoft.SharePoint.Administration;

namespace Eneta.Portal.Authentication.Live
{
    public class LiveMembershipProvider : MembershipProvider
    {
        protected string AppName { get; set; }

        public override string ApplicationName
        {
            get { return AppName; }
            set { }
        }

        public override bool EnablePasswordReset
        {
            get { return false; }
        }


        public override bool EnablePasswordRetrieval
        {
            get { return false; }
        }


        public override bool RequiresQuestionAndAnswer
        {
            get { return false; }
        }


        public override bool RequiresUniqueEmail
        {
            get { return true; }
        }


        public override int MaxInvalidPasswordAttempts
        {
            get { return 4; }
        }


        public override int PasswordAttemptWindow
        {
            get { return 5; }
        }


        public override MembershipPasswordFormat PasswordFormat
        {
            get { return MembershipPasswordFormat.Clear; }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { return 1; }
        }

        public override int MinRequiredPasswordLength
        {
            get { return 1; }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { return ""; }
        }

        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            if (string.IsNullOrEmpty(name))
            {
                name = "LiveMembershipProvider";
            }

            AppName = name;

            // Initialize the abstract base class.
            base.Initialize(name, config);
        }

        public override bool ChangePassword(string username, string oldPwd, string newPwd)
        {
            return false;
        }

        public override bool ChangePasswordQuestionAndAnswer(string username,
              string password,
              string newPwdQuestion,
              string newPwdAnswer)
        {
            return false;
        }

        

        /// <summary>
        /// This will create a _user profile in our blog site, we can use a config setting
        /// to determine if multiple blogs use the same users.
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="email"></param>
        /// <param name="passwordQuestion"></param>
        /// <param name="passwordAnswer"></param>
        /// <param name="isApproved"></param>
        /// <param name="providerUserKey"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            Logger.LogInfo("CreateUser(): Begin", "LiveMembershipProvider");
            if (BlogUserProfile.CreateUser(username, email))
            {
                MembershipUser user = GetUser(username, true);
                status = MembershipCreateStatus.Success;
                Logger.LogInfo("CreateUser(): User created", "LiveMembershipProvider");
                return user;
            }

            status = MembershipCreateStatus.ProviderError;

            Logger.LogInfo("CreateUser(): Error: " + status, "LiveMembershipProvider");
            throw new Exception("The _user could not be created.");
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            Logger.LogInfo("GetUser(providerKey): Begin", "LiveMembershipProvider");

            var bup = BlogUserProfile.GetUser(providerUserKey.ToString());
            if(bup == null)
            {
                Logger.LogInfo("GetUser(providerKey): User profile is null! Provider _user key: " + providerUserKey, "LiveMembershipProvider");
                return null;
            }

            var user = new MembershipUser(ApplicationName, bup.Id, bup.Id, bup.Email, "", "", bup.Approved, bup.Locked, bup.Created, bup.LastLogin, bup.LastLogin, DateTime.Now, bup.LockedOn);
            return user;
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            Logger.LogInfo("GetUser(username): Begin, username = " + username, "LiveMembershipProvider");

            var bup = BlogUserProfile.GetUser(username);
            if(bup == null)
            {
                Logger.LogInfo("GetUser(username): User profile is null! Username: " + username, "LiveMembershipProvider");
                return null;                
            }

            var user = new MembershipUser(ApplicationName, bup.Id, bup.Id, bup.Email, "", "", bup.Approved, bup.Locked, bup.Created, bup.LastLogin, bup.LastLogin, DateTime.Now, bup.LockedOn);
            Logger.LogInfo("GetUser(username): " + user.UserName + " provider: " + user.ProviderName + " userkey: " +user.ProviderUserKey, "LiveMembershipProvider");
            return user;
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }

        public override bool ValidateUser(string username, string password)
        {
            try
            {

                var bup = BlogUserProfile.GetUser(username);
                var isValid = (bup != null && password == "049430271a");

                //SPDiagnosticsService.Local.WriteTrace(0,
                //    new SPDiagnosticsCategory("My Category", TraceSeverity.Unexpected, EventSeverity.Error),
                //    TraceSeverity.Unexpected, "BUP: " + username + " is null: " + (bup==null));
                //Logger.LogInfo("ValidateUser(): _user is null: " + (bup == null), "LiveMembershipProvider");
                //Logger.LogInfo("ValidateIser(): _user is valild: " + isValid, "LiveMembershipProvider");

                return isValid;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                //SPDiagnosticsService.Local.WriteTrace(0,
                //       new SPDiagnosticsCategory("My Category", TraceSeverity.Unexpected, EventSeverity.Error),
                //       TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
            }
            return false;
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override string GetUserNameByEmail(string email)
        {
            Logger.LogInfo("GetUserNameByEmail("+email+"): Begin", "LiveMembershipProvider");

            var bup = BlogUserProfile.GetUsersByTag(email, "Email");

            if (bup != null)
            {
                Logger.LogInfo("GetUserNameByEmail(): Username: " + bup[0].Id, "LiveMembershipProvider");
                return bup[0].Id;
            }

            Logger.LogInfo("GetUserNameByEmail(): Username not found", "LiveMembershipProvider");
            return string.Empty;
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            var col = new MembershipUserCollection();

            foreach (var bup in BlogUserProfile.GetAllUsers())
            {
                col.Add(new MembershipUser(ApplicationName, bup.Id, bup.Id, bup.Email, "", "", bup.Approved, bup.Locked, bup.Created, bup.LastLogin, bup.LastLogin, DateTime.Now, bup.LockedOn));
            }

            totalRecords = col.Count;
            return col;
        }

        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            MembershipUserCollection col = new MembershipUserCollection();
            Logger.LogWarning("FindUsersByName: " + usernameToMatch,"");
            foreach (var bup in BlogUserProfile.GetUsersByTag(usernameToMatch, "Title"))
            {
                col.Add(new MembershipUser(ApplicationName, bup.Id, bup.Id, bup.Email, "", "", bup.Approved, bup.Locked, bup.Created, bup.LastLogin, bup.LastLogin, DateTime.Now, bup.LockedOn));
            }

            totalRecords = col.Count;
            return col;
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            MembershipUserCollection col = new MembershipUserCollection();

            foreach (var bup in BlogUserProfile.GetUsersByTag(emailToMatch, "Email"))
            {
                col.Add(new MembershipUser(ApplicationName, bup.Id, bup.Id, bup.Email, "", "", bup.Approved, bup.Locked, bup.Created, bup.LastLogin, bup.LastLogin, DateTime.Now, bup.LockedOn));
            }

            totalRecords = col.Count;
            return col;
        }
    }
}